"""测试会议安排系统的各个组件"""
import json
import sys
sys.path.append('.')

from meeting.meeting_agent_env import MeetingScheduleEnv
from meeting_reward import MeetingReward
import projection as proj


def test_projection():
    """测试动作解析"""
    print("="*60)
    print("测试动作解析模块")
    print("="*60)
    
    test_cases = [
        # 测试1: 查询日历
        """
<think>
首先需要查询所有参会人员的日历，了解他们的空闲时间。
</think>
<action>
查询李明和王芳的下周日历
</action>
<invoke>
{
    "tool_name": "query_calendar",
    "tool_input": {
        "persons": ["李明", "王芳"],
        "time_range": "next_week"
    }
}
</invoke>
        """,
        # 测试2: 最终答案
        """
<think>
根据查询结果，周一下午最合适，决定选择这个时间。
</think>
<answer>
{
    "tool_name": "select_time",
    "tool_input": {
        "day": "Monday",
        "time_slot": "afternoon"
    }
}
</answer>
        """,
        # 测试3: 协商
        """
<think>
李明在周一下午有安排，需要与他协商。
</think>
<action>
与李明协商周一下午的时间
</action>
<invoke>
{
    "tool_name": "negotiate_time",
    "tool_input": {
        "person": "李明",
        "day": "Monday",
        "time_slot": "afternoon"
    }
}
</invoke>
        """
    ]
    
    for i, test_case in enumerate(test_cases, 1):
        print(f"\n测试用例 {i}:")
        actions, invokes, valids = proj.meeting_projection([test_case])
        
        print(f"  有效性: {valids[0]}")
        print(f"  动作: {json.dumps(actions[0], ensure_ascii=False, indent=2)}")
        print(f"  调用: {json.dumps(invokes[0], ensure_ascii=False, indent=2)}")


def test_environment():
    """测试环境"""
    print("\n" + "="*60)
    print("测试会议安排环境")
    print("="*60)
    
    env = MeetingScheduleEnv(max_steps=10)
    
    # 创建测试任务
    task_data = {
        'meeting_topic': '产品规划会',
        'required_attendees': ['李明', '王芳'],
        'optional_attendees': ['陈静', '刘强'],
        'availability': {
            '李明': {
                'Monday': {'morning': 'available', 'afternoon': 'busy', 'evening': 'available'},
                'Tuesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'available'},
                'Wednesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'busy'},
            },
            '王芳': {
                'Monday': {'morning': 'busy', 'afternoon': 'available', 'evening': 'available'},
                'Tuesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'busy'},
                'Wednesday': {'morning': 'busy', 'afternoon': 'busy', 'evening': 'available'},
            },
            '陈静': {
                'Monday': {'morning': 'available', 'afternoon': 'available', 'evening': 'available'},
                'Tuesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'available'},
                'Wednesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'available'},
            },
            '刘强': {
                'Monday': {'morning': 'available', 'afternoon': 'busy', 'evening': 'available'},
                'Tuesday': {'morning': 'busy', 'afternoon': 'available', 'evening': 'available'},
                'Wednesday': {'morning': 'available', 'afternoon': 'available', 'evening': 'available'},
            },
        },
        'historical_pattern': {
            'most_common_day': 'Monday',
            'most_common_slot': 'afternoon',
            'frequency': 80
        }
    }
    
    # 重置环境
    observation, info = env.reset(task_data)
    print(f"\n初始观察:\n{observation}")
    print(f"\n任务信息: {json.dumps(info, ensure_ascii=False)}")
    
    # 测试查询日历
    print("\n\n--- 步骤1: 查询日历 ---")
    action = {
        'tool_name': 'query_calendar',
        'tool_input': {
            'persons': ['李明', '王芳'],
            'time_range': 'next_week'
        }
    }
    obs, reward, done, info = env.step(action, True)
    print(f"观察: {obs[:200]}...")
    print(f"奖励: {reward}")
    print(f"完成: {done}")
    
    # 测试查询历史
    print("\n\n--- 步骤2: 查询历史 ---")
    action = {
        'tool_name': 'query_history',
        'tool_input': {
            'meeting_topic': '产品规划会'
        }
    }
    obs, reward, done, info = env.step(action, True)
    print(f"观察: {obs}")
    print(f"奖励: {reward}")
    print(f"完成: {done}")
    
    # 测试选择时间
    print("\n\n--- 步骤3: 选择时间（周二上午） ---")
    action = {
        'tool_name': 'select_time',
        'tool_input': {
            'day': 'Tuesday',
            'time_slot': 'morning'
        }
    }
    obs, reward, done, info = env.step(action, True)
    print(f"观察: {obs}")
    print(f"最终奖励: {reward}")
    print(f"完成: {done}")


def test_reward():
    """测试奖励计算"""
    print("\n" + "="*60)
    print("测试奖励计算")
    print("="*60)
    
    reward_calc = MeetingReward()
    
    # 测试状态
    state = {
        'required_attendees': ['李明', '王芳'],
        'optional_attendees': ['陈静', '刘强', '赵敏'],
        'availability': {
            '李明': {'Monday': {'afternoon': 'available'}},
            '王芳': {'Monday': {'afternoon': 'available'}},
            '陈静': {'Monday': {'afternoon': 'available'}},
            '刘强': {'Monday': {'afternoon': 'busy'}},
            '赵敏': {'Monday': {'afternoon': 'available'}},
        },
        'historical_pattern': {
            'most_common_day': 'Monday',
            'most_common_slot': 'afternoon',
            'frequency': 80
        },
        'negotiation_history': []
    }
    
    selected_time = {
        'day': 'Monday',
        'time_slot': 'afternoon'
    }
    
    final_reward = reward_calc.final_reward(state, selected_time)
    print(f"\n最终奖励: {final_reward}")
    print(f"  - 必选人员: 2/2 (全部参加)")
    print(f"  - 可选人员: 2/3 (陈静、赵敏参加)")
    print(f"  - 协商次数: 0")
    print(f"  - 历史匹配: 是 (80%频率)")
    print(f"  - 计算: 0 (必选全到) + 2 (2个可选) - 0 (0次协商) + 4 (历史匹配0.8*5) = {final_reward}")


def main():
    """运行所有测试"""
    print("\n" + "█"*60)
    print("█" + " "*58 + "█")
    print("█" + " "*15 + "会议安排系统测试" + " "*15 + "█")
    print("█" + " "*58 + "█")
    print("█"*60 + "\n")
    
    try:
        test_projection()
        test_environment()
        test_reward()
        
        print("\n\n" + "="*60)
        print("✅ 所有测试通过！")
        print("="*60)
        print("\n系统组件工作正常，可以开始训练。")
        
    except Exception as e:
        print(f"\n\n❌ 测试失败: {str(e)}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    main()

